package jmine.tec.proxy.javassist;

import java.io.Serializable;
import java.lang.reflect.Method;

import javassist.util.proxy.MethodHandler;
import jmine.tec.proxy.chain.ChainElement;
import jmine.tec.proxy.chain.DelegatingInvocationChain;
import jmine.tec.proxy.chain.InvocationChain;

/**
 * The {@link MethodHandler} that uses the chain elements
 * @author MarceloT
 */
public class ChainedMethodHandler implements MethodHandler, Serializable {

    private final ChainElement[] chainElements;

    private final Object delegate;

    /**
     * C'tor
     * @param delegate the delegate
     * @param chainElements the chain elements
     */
    public ChainedMethodHandler(Object delegate, ChainElement... chainElements) {
        super();
        this.chainElements = chainElements;
        this.delegate = delegate;
    }

    /**
     * @param self the proxy
     * @param thisMethod the method being invoked
     * @param proceed the proceeding method
     * @param args the arguments of the method
     * @throws Throwable t
     * @return the return value
     */
    public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
        InvocationChain chain = new DelegatingInvocationChain(delegate, chainElements, thisMethod, self, args);
        return chain.proceed();
    }

}
